package com.boot.limit.factory.impl;

import com.boot.limit.factory.SmsLimitService;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.scripting.support.ResourceScriptSource;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SmsLimitServiceImpl implements SmsLimitService {


    /**
     * 短信限速：间隔 ，单位秒
     * 可选
     */
    private int smsLimitIntervalSecond = 1;
    /**
     * 短信限速：间隔内产生的令牌数
     * 可选
     */
    private int smsLimitIntervalCount = 60;
    /**
     * 短信限速：桶内最大令牌数
     * 可选
     */
    private int smsLimitMaxCount = 80;


    public static final String LOG_PREF = "redis短信限速";

    RedisTemplate redisTemplate;
     DefaultRedisScript<Long> redisScript;

    /**
     * @param redisTemplate
     * @param smsLimitIntervalSecond 短信限速间隔
     * @param smsLimitIntervalCount 每次间隔产生的令牌
     * @param smsLimitMaxCount 桶里面最大的令牌数量
     */
    public SmsLimitServiceImpl(RedisTemplate redisTemplate,int smsLimitIntervalSecond, int smsLimitIntervalCount, int smsLimitMaxCount) {
        this.redisTemplate = redisTemplate;
        this.smsLimitIntervalSecond = smsLimitIntervalSecond;
        this.smsLimitIntervalCount = smsLimitIntervalCount;
        this.smsLimitMaxCount = smsLimitMaxCount;
        redisScript = new DefaultRedisScript<>();
        redisScript.setResultType(Long.class);
        redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/sms_limit.lua")));

//        redisScript.setScriptText(lua);

    }

    /** 获取令牌
     * @param provCode    省份
     * @param expectCount 想获取的令牌
     * @param isVip       是否vip
     * @return
     */
    @Override
    public Object consumeTokenCount(String provCode, int expectCount, boolean isVip) {
        List<String> keys = new ArrayList<>();
        keys.add("a:k");
        /**
         * -- ARGV[1]  int     桶最大容量
         * -- ARGV[2]  int     每次添加令牌数
         * -- ARGV[3]  int     令牌添加间隔(秒)
         * -- ARGV[4]  int     想获取令牌的数量
         * -- ARGV[5]  int     是否vip 0-否  1-时
         */
        Object result = redisTemplate.execute(redisScript, keys,
                smsLimitMaxCount+"",
                smsLimitIntervalCount+"",
                smsLimitIntervalSecond+"",
                expectCount+"",
                (isVip ? 1 : 0)+"");

        return result;
    }
}
